#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<variant>


#include"src/utils/imageembedder.h"
#include"src/utils/textembedder.h"
#include"src/utils/vectordb/vectordb.h"

using namespace std;

// embedding 文本并嵌入数据库
void EmbeddingT(VectorDB& db_Text,const string &collectionName,const string& text){
    TextEmbedder tem;
    vector<float> Text_EmV = tem.embeddingText(text);

    vector<double> Text_Em;
    //将float类型的向量转换成vector<double>类型
    for(float f : Text_EmV){
        Text_Em.push_back(static_cast<double>(f));
    }

    // embedding后 add到collection
    variant<string, int64_t> v;
    v =  "cosine";
    map<string, variant<string, int64_t>> metadata_example;
    metadata_example.insert(make_pair("hnsw:space",v));

    VectorData vd{"1", Text_Em, metadata_example, "Jack"};
    const vector<VectorData> vinsert = {vd};
    db_Text.addData(collectionName, vinsert);
}

// embedding 图片并嵌入数据库
void EmbeddingI(VectorDB& db_Ima,const string &collectionName,const string& filePath){
    ImageEmbedder iem;

    vector<float> Ima_EmV = iem.embeddingImage(filePath);

    vector<double> Ima_Em;

    for(float f : Ima_EmV){
        Ima_Em.push_back(static_cast<double>(f));
    }

    //embedding后 add到collection
    variant<string, int64_t> VIma;
    VIma =  "cosine";

    map<string, variant<string, int64_t>> metadata_exampleImage;
    metadata_exampleImage.insert(make_pair("hnsw:space",VIma));

    VectorData vdIma{"20", Ima_Em, metadata_exampleImage, "Jack"};
    const vector<VectorData> vinsert_Ima = {vdIma};
    db_Ima.addData(collectionName, vinsert_Ima);
}

//文搜文
vector<pair<VectorData, float>> text_Search(VectorDB& db_Text,const string &collectionName,const string& text){

    TextEmbedder tem;
    vector<float> Text_EmV_Search = tem.embeddingText(text);

    vector<double> Text_Em_Search;
    //将float类型的向量转换成vector<double>类型
    for(float f : Text_EmV_Search){
        Text_Em_Search.push_back(static_cast<double>(f));
    }

    vector<vector<double>> Embeddings_Text_Search = {Text_Em_Search};

    return db_Text.queryData(collectionName,Embeddings_Text_Search);
}

//文搜图
vector<pair<VectorData, float>> Image_Search(VectorDB& db_Ima,const string &collectionName,const string& text){

    ImageEmbedder iem;
    vector<float> Ima_Emv_Search = iem.embeddingText(text);

    vector<double> Ima_Em_Search;

    for(float f : Ima_Emv_Search){
        Ima_Em_Search.push_back(static_cast<double>(f));
    }

    vector<vector<double>> Embeddings_Image_Search = {Ima_Em_Search};

    return db_Ima.queryData(collectionName ,Embeddings_Image_Search);
}

// 打印结果
void print(vector<pair<VectorData, float>> &result_Text){
    for (const auto& pair : result_Text) {
    const VectorData& data = pair.first;
    float score = pair.second;

    cout << "ID: " << data.id << ", Score: " << score << endl;
    cout << "Embedding: "; //query 回来的Embedding是空的
    for (double emb : data.embedding) {
        std::cout << emb << " ";
    }
    cout << endl;
    cout << "Metadata:" << endl;
    for (const auto& entry : data.metadata) {
        cout << "  " << entry.first << ": ";

        cout<<get<string>(entry.second);
        // visit([](const auto& val) {
        //     cout << val;
        // }, entry.second);
        cout << std::endl;
    }
    cout << "Document: " << data.document << endl;
    }
    std::cout << "----------------------------------------------------" << std::endl;
}

int main()
{
    // // 手动embedding后，看看矢量化后的数据
    // ImageEmbedder im;
    // std::vector<float> result =  im.embeddingText("问心一言,chatgpt,讯飞,豆包,小天,kylinOS");
    // for(auto i : result){
    //     std::cout<<i<<"   ";
    // }
    // TextEmbedder tm;
    // std::vector<float> result =  tm.embeddingText("问心一言,chatgpt,讯飞,豆包,小天,kylinOS");
    // for(auto i : result){
    //     std::cout<<i<<"   ";
    // }


    ImageEmbedder im;
    std::vector<float> result =  im.embeddingImage("/home/ukylin/demo/testIndex/asdf.jpg");
    for(auto i : result){
        std::cout<<i<<"   ";
    }
    std::cout<<"------------------------------------------------------------"<<std::endl;
    //创建文本的collection
    // const string& collectionName_Text = "MyCollection_Text";
    // VectorDB db_Text("/home/ukylin/demo/testIndex");
    // db_Text.createCollection(collectionName_Text,"bge-base-zh-v1.5");

    //创建图片的collection
    const string& collectionName_Ima = "MyCollection_Ima";
    VectorDB db_Ima("/home/ukylin/demo/testIndex");
    db_Ima.createCollection(collectionName_Ima,"bge-base-zh-v1.5");


    //EmbeddingT(db_Text,collectionName_Text,"love you");
    //vector<pair<VectorData, float>> result_Text =  text_Search(db_Text,collectionName_Text,"love");
    // 显示query后的结果
    //print(result_Text);


    EmbeddingI(db_Ima,collectionName_Ima,"/home/ukylin/demo/testIndex/asdf.jpg");
    vector<pair<VectorData, float>> result_Ima =  Image_Search(db_Ima,collectionName_Ima,"小狗");
    //显示query后的结果
    print(result_Ima);


    std::cout << "Hello World!" << std::endl;
    return 0;



    // //发现图片和文本存入一个数据库会有问题
    // //创建文本的collection
    // const string& collectionName_Text = "MyCollection_Text";
    // VectorDB db_Text("/home/kylinW/bug/testBase");
    // db_Text.createCollection(collectionName_Text,"bge-base-zh-v1.5");

    // //创建图片的collection
    // const string& collectionName_Ima = "MyCollection_Ima";
    // VectorDB db_Ima("/home/kylinW/bug/testBase");
    // db_Ima.createCollection(collectionName_Ima,"bge-base-zh-v1.5");


    // // 文本嵌入
    // // 通过embedding模型嵌入
    // TextEmbedder tem;
    // vector<float> Text_EmV = tem.embeddingText("KylinSoftware,love work");

    // vector<double> Text_Em;
    // //将float类型的向量转换成vector<double>类型
    // for(float f : Text_EmV){
    //     Text_Em.push_back(static_cast<double>(f));
    // }

    // // embedding后 add到collection
    // variant<string, int64_t> v;
    // v =  "cosine";
    // map<string, variant<string, int64_t>> metadata_example;
    // metadata_example.insert(make_pair("hnsw:space",v));

    // VectorData vd{"1", Text_Em, metadata_example, "Jack"};
    // const vector<VectorData> vinsert = {vd};
    // db_Text.addData(collectionName_Text, vinsert);


    // //图片嵌入
    // //通过embedding模型嵌入
    // ImageEmbedder iem;

    // vector<float> Ima_EmV = iem.embeddingImage("/home/kylinW/bug/image/1.jpg");

    // vector<double> Ima_Em;

    // for(float f : Ima_EmV){
    //     Ima_Em.push_back(static_cast<double>(f));
    // }

    // //embedding后 add到collection
    // variant<string, int64_t> VIma;
    // VIma =  "cosine";

    // map<string, variant<string, int64_t>> metadata_exampleImage;
    // metadata_exampleImage.insert(make_pair("hnsw:space",VIma));

    // VectorData vdIma{"20", Ima_Em, metadata_exampleImage, "Jack"};
    // const vector<VectorData> vinsert_Ima = {vdIma};
    // db_Ima.addData(collectionName_Ima, vinsert_Ima);



    // // 图片embedding后保存到我们的数据库，此时进行文搜图的操作

    // //文搜文
    // vector<float> Text_EmV_Search = tem.embeddingText("love");

    // vector<double> Text_Em_Search;
    // //将float类型的向量转换成vector<double>类型
    // for(float f : Text_EmV_Search){
    //     Text_Em_Search.push_back(static_cast<double>(f));
    // }

    // vector<vector<double>> Embeddings_Text_Search = {Text_Em_Search};

    // vector<pair<VectorData, float>> result_Text = db_Text.queryData(collectionName_Text,Embeddings_Text_Search);

    // // 显示query后的结果
    //     for(vector<pair<VectorData,float>>::iterator it = result_Text.begin(); it != result_Text.end() ; it++){
    //     cout << "VectorData的数据: "<<" id: "<<it->first.id
    //     <<" document: "<<it->first.document
    //     <<endl;
    // }

    // cout<<"------------------------------------------------------------------------"<<endl;

    // //文搜图
    // vector<float> Ima_Emv_Search = iem.embeddingText("鸟");

    // vector<double> Ima_Em_Search;

    // for(float f : Ima_Emv_Search){
    //     Ima_Em_Search.push_back(static_cast<double>(f));
    // }

    // vector<vector<double>> Embeddings_Image_Search = {Ima_Em_Search};

    // vector<pair<VectorData, float>> result_Ima = db_Ima.queryData(collectionName_Ima,Embeddings_Image_Search);

    // // 显示query后的结果
    // for(vector<pair<VectorData,float>>::iterator it = result_Ima.begin() ; it != result_Ima.end() ; it++){
    //     cout << "VectorData的数据: "<<" id: "<<it->first.id
    //     <<" document: "<<it->first.document
    //     <<endl;
    // }

    // cout<<"------------------------------------------------------------------------"<<endl;
}
